const obj = {
  name: 'Yeoman',
  age: 18,
  a: {
    b: 'origin'
  }
}

function checkType (target) {
  return Object.prototype.toString.call(target).slice(8, -1)
}

function deepClone (target) {
  let res
  const type = checkType(target)
  if ('Object' === type)  res = {}
  else if ('Array' === type)  res = []
  else  return target
  for (let key in target) {
    const val = target[key]
    if ('Object' === checkType(val) || 'Array' === checkType(val)) {
      res[key] = deepClone(val)
    } else {
      res[key] = val
    }
  }
  return res
}

function clone(target, map = new Map()) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        if (map.get(target)) {
            return map.get(target);
        }
        map.set(target, cloneTarget);
        for (const key in target) {
            cloneTarget[key] = clone(target[key], map);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

const obj2 = deepClone(obj)
obj2.name = 'LYM'
obj2.age = 23
obj2.a.b = 'change!'

console.log('obj', obj)
console.log('obj2', obj2)

let o = {
  a: 1,
  b: {
    c: 2
  }
}
o.c = o.b
o.b.c = o.c
// console.log(o)
let newO = JSON.parse(JSON.stringify(o))
console.log(newO)
